enum DateFormatter { y, ym, ymd, hms, md, hm, ymdhm, ymdhms, ymdam, quarter }

extension DateFormatEx on DateTime {
  String format(
    DateFormatter formatter, {
    String s1 = '-',
    String s2 = ':',
    bool unit = false,
  }) {
    final y = year.toString();
    final m = month.toString().padLeft(2, '0');
    final d = day.toString().padLeft(2, '0');
    final h = hour.toString().padLeft(2, '0');
    final mm = minute.toString().padLeft(2, '0');
    final s = second.toString().padLeft(2, '0');

    switch (formatter) {
      case DateFormatter.y:
        return y;
      case DateFormatter.quarter:
        return '$y年第$quarter季度';
      case DateFormatter.ym:
        if (unit) {
          return '$y年$m月';
        }
        return '$y$s1$m';
      case DateFormatter.ymd:
        if (unit) {
          return '$y年$m月$d日';
        }
        return '$y$s1$m$s1$d';
      case DateFormatter.hms:
        if (unit) {
          return '$h小时$mm分钟$s秒';
        }
        return '$h$s2$mm$s2$s';
      case DateFormatter.md:
        if (unit) {
          return '$m月$d日';
        }
        return '$m$s1$d';
      case DateFormatter.hm:
        if (unit) {
          return '$h小时$mm分钟';
        }
        return '$h$s2$mm$s2';
      case DateFormatter.ymdhm:
        if (unit) {
          return '$y年$m月$d日 $h小时$mm分钟';
        }
        return '$y$s1$m$s1$d $h$s2$mm';
      case DateFormatter.ymdam:
        final am = hour <= 12 ? '上午' : '下午';
        if (unit) {
          return '$y年$m月$d日 $am';
        }
        return '$y$s1$m$s1$d $am';
      default:
        if (unit) {
          return '$y年$m月$d日 $h小时$mm分钟$s秒';
        }
        return '$y$s1$m$s1$d $h$s2$mm$s2$s';
    }
  }

  int get monthDays {
    if (month == 2) {
      if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
        return 29;
      } else {
        return 28;
      }
    } else if (month == 1 ||
        month == 3 ||
        month == 5 ||
        month == 7 ||
        month == 8 ||
        month == 10 ||
        month == 12) {
      return 31;
    } else {
      return 30;
    }
  }
}

extension DateEx on DateTime {
  DateTime after({
    int year = 0,
    int month = 0,
    int day = 0,
    int hour = 0,
    int minute = 0,
    int second = 0,
  }) {
    return DateTime(
      this.year + year,
      this.month + month,
      this.day + day,
      this.hour + hour,
      this.minute + minute,
      this.second + second,
    );
  }

  int get quarter {
    switch (month) {
      case 1:
      case 2:
      case 3:
        return 1;
      case 4:
      case 5:
      case 6:
        return 2;
      case 7:
      case 8:
      case 9:
        return 3;
      case 10:
      case 11:
      case 12:
        return 4;
      default:
        return 1;
    }
  }
}

extension QuarterEx on int {
  int get quarterStart {
    switch (this) {
      case 1:
        return 1;
      case 2:
        return 4;
      case 3:
        return 7;
      case 4:
        return 10;
      default:
        return 1;
    }
  }

  int get quarterEnd {
    switch (this) {
      case 1:
        return 3;
      case 2:
        return 6;
      case 3:
        return 9;
      case 4:
        return 12;
      default:
        return 3;
    }
  }
}
